import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'dart:async';

/// 自定义时间刻度尺组件
/// 完全自定义实现，左侧时间和刻度尺合并为一个滚动区域
class TimeRulerWidget extends StatefulWidget {
  final DateTime? selectedTime;
  final Function(DateTime)? onTimeSelected;
  final List<Map<String, dynamic>>? recordSegments;
  final bool isVertical;
  final DateTime? selectedDate; // 新增：选中的日期

  const TimeRulerWidget({
    super.key,
    this.selectedTime,
    this.onTimeSelected,
    this.recordSegments,
    this.isVertical = false,
    this.selectedDate, // 新增参数
  });

  @override
  State<TimeRulerWidget> createState() => _TimeRulerWidgetState();
}

class _TimeRulerWidgetState extends State<TimeRulerWidget> {
  late ScrollController _scrollController;
  late DateTime _today;
  late DateTime _currentTime;
  DateTime? _currentScrollTime; // 当前滚动位置对应的时间
  Timer? _scrollEndTimer; // 滚动结束计时器
  bool _isScrolling = false; // 是否正在滚动
  bool _isProgrammaticScroll = false; // 是否是程序化滚动（避免触发播放）
  double _lastScrollOffset = 0.0; // 上次滚动位置，用于检测滚动是否停止

  // 时间轴配置常量 - 统一定义，确保一致性
  static const double hourHeight = 120.0; // 垂直模式每小时的高度
  static const double verticalPadding = 20.0; // 上下内边距
  static const double totalHeight =
      24 * hourHeight + 2 * verticalPadding; // 总高度：2880px + 内边距
  static const double timeWidth = 30.0; // 时间显示区域宽度
  static const double scaleWidth = 130.0; // 刻度尺区域宽度
  static const double totalRulerWidth = timeWidth + scaleWidth; // 总宽度：200px

  @override
  void initState() {
    super.initState();
    // 使用选中的日期，如果没有则使用当前日期
    _today = widget.selectedDate ?? DateTime.now();
    _currentTime = DateTime.now();
    _scrollController = ScrollController();

    // ✅ 监听滚动位置变化，用于实时更新时间显示
    _scrollController.addListener(_onScrollPositionChanged);

    WidgetsBinding.instance.addPostFrameCallback((_) {
      // ✅ 在滚动控制器初始化后，添加滚动状态监听
      if (_scrollController.hasClients) {
        _scrollController.position.isScrollingNotifier.addListener(
          _onScrollStateChanged,
        );
      }

      if (widget.selectedTime != null) {
        _scrollToTime(widget.selectedTime!);
      } else {
        _scrollToCurrentTime();
      }
    });
  }

  @override
  void didUpdateWidget(TimeRulerWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    // 当选中日期改变时，更新_today
    if (oldWidget.selectedDate != widget.selectedDate) {
      _today = widget.selectedDate ?? DateTime.now();
      // 重新滚动到当前时间位置
      WidgetsBinding.instance.addPostFrameCallback((_) {
        _scrollToCurrentTime();
      });
    }
    // 当选中时间改变时，滚动到对应位置
    if (oldWidget.selectedTime != widget.selectedTime &&
        widget.selectedTime != null) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        _scrollToTime(widget.selectedTime!);
      });
    }
  }

  @override
  void dispose() {
    _scrollEndTimer?.cancel();
    // ✅ 移除滚动状态监听器
    if (_scrollController.hasClients) {
      _scrollController.position.isScrollingNotifier.removeListener(
        _onScrollStateChanged,
      );
    }
    _scrollController.dispose();
    super.dispose();
  }

  /// ✅ 滚动状态变化监听（使用ScrollPosition的isScrollingNotifier）
  void _onScrollStateChanged() {
    if (!mounted || !_scrollController.hasClients) return;

    final isCurrentlyScrolling =
        _scrollController.position.isScrollingNotifier.value;

    // ✅ 如果滚动从进行中变为停止，触发播放
    if (!isCurrentlyScrolling && _isScrolling) {
      // ✅ 滚动真正停止时，触发播放
      print('✅ 滚动已停止，准备触发播放');
      _handleScrollEnd();
    }

    // ✅ 更新滚动状态
    _isScrolling = isCurrentlyScrolling;
  }

  /// ✅ 滚动位置变化监听（用于实时更新时间显示）
  void _onScrollPositionChanged() {
    if (!mounted || !_scrollController.hasClients) return;

    // ✅ 如果是程序化滚动，不更新时间显示
    if (_isProgrammaticScroll) {
      return;
    }

    // 获取组件的实际高度
    final RenderBox? box = context.findRenderObject() as RenderBox?;
    final componentHeight =
        box?.size.height ?? MediaQuery.of(context).size.height;

    // 计算中心线位置对应的时间
    // 需要减去padding的偏移量，因为ScrollView的offset包含了padding
    final paddingOffset = 380.w; // 与SingleChildScrollView的padding保持一致
    final centerPosition =
        _scrollController.offset + componentHeight / 2 - paddingOffset;

    // ✅ 严格限制位置在有效范围内（00:00 到 24:00）
    // 有效范围：verticalPadding 到 totalHeight - verticalPadding
    final minPosition = verticalPadding;
    final maxPosition = totalHeight - verticalPadding;

    if (centerPosition < minPosition || centerPosition >= maxPosition) {
      // ✅ 如果超出范围，强制限制滚动位置
      if (centerPosition < minPosition) {
        // 滚动到顶部（00:00）
        final targetOffset = minPosition - componentHeight / 2 + paddingOffset;
        if (targetOffset >= 0 && _scrollController.hasClients) {
          _scrollController.jumpTo(
            targetOffset.clamp(0.0, _scrollController.position.maxScrollExtent),
          );
        }
        // 设置时间为 00:00:00
        final newTime = DateTime(
          _today.year,
          _today.month,
          _today.day,
          0,
          0,
          0,
        );
        if (_currentScrollTime == null || _currentScrollTime != newTime) {
          setState(() {
            _currentScrollTime = newTime;
          });
        }
      } else {
        // 滚动到底部（24:00，即第二天的 00:00，但显示为 24:00）
        final targetOffset = maxPosition - componentHeight / 2 + paddingOffset;
        if (targetOffset <= _scrollController.position.maxScrollExtent &&
            _scrollController.hasClients) {
          _scrollController.jumpTo(
            targetOffset.clamp(0.0, _scrollController.position.maxScrollExtent),
          );
        }
        // 设置时间为 23:59:59（最大有效时间）
        final newTime = DateTime(
          _today.year,
          _today.month,
          _today.day,
          23,
          59,
          59,
        );
        if (_currentScrollTime == null || _currentScrollTime != newTime) {
          setState(() {
            _currentScrollTime = newTime;
          });
        }
      }
      return;
    }

    // 计算对应的时间
    final contentPosition = centerPosition - verticalPadding;
    final hour = (contentPosition / hourHeight).floor();
    final minuteFraction = (contentPosition % hourHeight) / hourHeight;
    final minute = (minuteFraction * 60).floor();
    final second = ((minuteFraction * 60 - minute) * 60).floor();

    // ✅ 严格限制时间范围：hour 必须在 0-23 之间
    if (hour >= 0 && hour < 24) {
      final newTime = DateTime(
        _today.year,
        _today.month,
        _today.day,
        hour,
        minute.clamp(0, 59),
        second.clamp(0, 59),
      );

      // ✅ 更新当前滚动时间（只更新显示，不触发播放）
      if (_currentScrollTime == null ||
          _currentScrollTime!.hour != newTime.hour ||
          _currentScrollTime!.minute != newTime.minute ||
          _currentScrollTime!.second != newTime.second) {
        setState(() {
          _currentScrollTime = newTime;
        });
      }

      // ✅ 记录当前滚动位置，用于检测滚动是否停止
      _lastScrollOffset = _scrollController.offset;
    } else {
      // ✅ 如果计算出的时间超出范围，强制限制
      final clampedHour = hour.clamp(0, 23);
      final newTime = DateTime(
        _today.year,
        _today.month,
        _today.day,
        clampedHour,
        minute.clamp(0, 59),
        second.clamp(0, 59),
      );
      if (_currentScrollTime == null || _currentScrollTime != newTime) {
        setState(() {
          _currentScrollTime = newTime;
        });
      }
    }
  }

  /// ✅ 处理滚动结束事件
  void _handleScrollEnd() {
    if (!mounted || !_scrollController.hasClients) return;

    // ✅ 如果是程序化滚动，不触发播放
    if (_isProgrammaticScroll) {
      print('⚠️ 程序化滚动，不触发播放');
      return;
    }

    // ✅ 取消之前的计时器
    _scrollEndTimer?.cancel();

    // ✅ 记录当前滚动位置，用于检测滚动是否稳定
    _lastScrollOffset = _scrollController.offset;

    // ✅ 延迟300ms后触发播放（确保滚动完全停止）
    _scrollEndTimer = Timer(const Duration(milliseconds: 300), () {
      if (!mounted || !_scrollController.hasClients) return;

      // ✅ 再次检查滚动位置是否稳定（在300ms内没有变化）
      final currentOffset = _scrollController.offset;
      if ((currentOffset - _lastScrollOffset).abs() > 1.0) {
        // 滚动位置还在变化，继续等待
        print(
          '⏳ 滚动位置还在变化（${(currentOffset - _lastScrollOffset).abs()}px），继续等待...',
        );
        _handleScrollEnd();
        return;
      }

      // ✅ 再次检查是否是程序化滚动（可能在等待期间被设置为程序化滚动）
      if (_isProgrammaticScroll) {
        print('⚠️ 程序化滚动，不触发播放');
        _isProgrammaticScroll = false;
        return;
      }

      // ✅ 再次检查滚动状态（确保真正停止）
      if (_scrollController.position.isScrollingNotifier.value) {
        print('⏳ 滚动状态还在进行中，继续等待...');
        _handleScrollEnd();
        return;
      }

      // ✅ 获取当前时间并触发播放
      final RenderBox? box = context.findRenderObject() as RenderBox?;
      final componentHeight =
          box?.size.height ?? MediaQuery.of(context).size.height;
      final paddingOffset = 380.w;
      final centerPosition =
          _scrollController.offset + componentHeight / 2 - paddingOffset;

      // ✅ 严格限制位置在有效范围内（00:00 到 24:00）
      final minPosition = verticalPadding;
      final maxPosition = totalHeight - verticalPadding;

      if (centerPosition >= minPosition && centerPosition < maxPosition) {
        final contentPosition = centerPosition - verticalPadding;
        final hour = (contentPosition / hourHeight).floor();
        final minuteFraction = (contentPosition % hourHeight) / hourHeight;
        final minute = (minuteFraction * 60).floor();
        final second = ((minuteFraction * 60 - minute) * 60).floor();

        // ✅ 严格限制时间范围：hour 必须在 0-23 之间
        if (hour >= 0 && hour < 24) {
          final newTime = DateTime(
            _today.year,
            _today.month,
            _today.day,
            hour,
            minute.clamp(0, 59),
            second.clamp(0, 59),
          );

          print('✅ 滚动停止，触发播放: $newTime');
          widget.onTimeSelected?.call(newTime);
        } else {
          // ✅ 如果时间超出范围，不触发播放
          print('⚠️ 时间超出有效范围（00:00-24:00），不触发播放');
        }
      } else {
        // ✅ 如果位置超出范围，不触发播放
        print('⚠️ 滚动位置超出有效范围，不触发播放');
      }
    });
  }

  /// 滚动到当前时间位置
  void _scrollToCurrentTime() {
    if (!widget.isVertical || !mounted) return;

    // ✅ 标记为程序化滚动，避免触发播放
    _isProgrammaticScroll = true;

    // ✅ 取消之前的计时器
    _scrollEndTimer?.cancel();

    // ✅ 严格限制时间范围：hour 必须在 0-23 之间
    final currentHour = _currentTime.hour.clamp(0, 23);
    final currentMinute = _currentTime.minute.clamp(0, 59);

    // ✅ 计算位置，确保在有效范围内
    final currentPosition =
        verticalPadding + (currentHour + currentMinute / 60.0) * hourHeight;

    // ✅ 确保位置不超过最大有效位置（24:00 对应 totalHeight - verticalPadding）
    final maxPosition = totalHeight - verticalPadding;
    final clampedPosition = currentPosition.clamp(verticalPadding, maxPosition);

    // 获取组件的实际高度
    final RenderBox? box = context.findRenderObject() as RenderBox?;
    final componentHeight =
        box?.size.height ?? MediaQuery.of(context).size.height;

    // 需要加上padding偏移量，因为ScrollView会自动处理padding
    final paddingOffset = 380.w; // 与SingleChildScrollView的padding保持一致

    // ✅ 计算滚动位置，确保不会超出有效范围
    final scrollPosition = (clampedPosition -
            componentHeight / 2 +
            paddingOffset)
        .clamp(0.0, totalHeight - componentHeight + 2 * paddingOffset);

    if (_scrollController.hasClients) {
      _scrollController
          .animateTo(
            scrollPosition,
            duration: const Duration(milliseconds: 500),
            curve: Curves.easeInOut,
          )
          .then((_) {
            // ✅ 滚动动画完成后，重置程序化滚动标记
            Future.delayed(const Duration(milliseconds: 100), () {
              _isProgrammaticScroll = false;
            });
          });
    }
  }

  /// 滚动到指定时间位置
  void _scrollToTime(DateTime time) {
    if (!widget.isVertical || !mounted) return;

    // ✅ 标记为程序化滚动，避免触发播放
    _isProgrammaticScroll = true;

    // ✅ 取消之前的计时器
    _scrollEndTimer?.cancel();

    // ✅ 严格限制时间范围：hour 必须在 0-23 之间
    final hour = time.hour.clamp(0, 23);
    final minute = time.minute.clamp(0, 59);
    final second = time.second.clamp(0, 59);

    // ✅ 计算位置，确保在有效范围内
    final position =
        verticalPadding + (hour + minute / 60.0 + second / 3600.0) * hourHeight;

    // ✅ 确保位置不超过最大有效位置（24:00 对应 totalHeight - verticalPadding）
    final maxPosition = totalHeight - verticalPadding;
    final clampedPosition = position.clamp(verticalPadding, maxPosition);

    // 获取组件的实际高度
    final RenderBox? box = context.findRenderObject() as RenderBox?;
    final componentHeight =
        box?.size.height ?? MediaQuery.of(context).size.height;

    // 需要加上padding偏移量，因为ScrollView会自动处理padding
    final paddingOffset = 380.w; // 与SingleChildScrollView的padding保持一致

    // ✅ 计算滚动位置，确保不会超出有效范围
    final scrollPosition = (clampedPosition -
            componentHeight / 2 +
            paddingOffset)
        .clamp(0.0, totalHeight - componentHeight + 2 * paddingOffset);

    if (_scrollController.hasClients) {
      _scrollController
          .animateTo(
            scrollPosition,
            duration: const Duration(milliseconds: 300),
            curve: Curves.easeInOut,
          )
          .then((_) {
            // ✅ 滚动动画完成后，重置程序化滚动标记
            Future.delayed(const Duration(milliseconds: 100), () {
              _isProgrammaticScroll = false;
            });
          });
    }
  }

  @override
  Widget build(BuildContext context) {
    if (!widget.isVertical) {
      return _buildHorizontalTimeRuler();
    }
    return _buildVerticalTimeRuler();
  }

  /// 构建垂直时间刻度尺
  Widget _buildVerticalTimeRuler() {
    return Container(
      width: double.infinity,
      color: const Color(0xFFEDF3FA), // 整体背景颜色
      child: Stack(
        children: [
          // 整个区域都可以滑动
          NotificationListener<ScrollNotification>(
            onNotification: (notification) {
              // ✅ 监听滚动通知，限制滚动范围
              if (notification is ScrollUpdateNotification &&
                  _scrollController.hasClients) {
                final paddingOffset = 380.w;
                final componentHeight = MediaQuery.of(context).size.height;
                final maxScrollExtent =
                    totalHeight - componentHeight + 2 * paddingOffset;

                // ✅ 计算当前中心线对应的位置
                final centerPosition =
                    _scrollController.offset +
                    componentHeight / 2 -
                    paddingOffset;
                final minPosition = verticalPadding;
                final maxPosition = totalHeight - verticalPadding;

                // ✅ 如果超出范围，强制限制滚动位置
                if (centerPosition < minPosition) {
                  // 滚动到顶部（00:00）
                  final targetOffset =
                      minPosition - componentHeight / 2 + paddingOffset;
                  if (targetOffset >= 0) {
                    WidgetsBinding.instance.addPostFrameCallback((_) {
                      if (_scrollController.hasClients) {
                        _scrollController.jumpTo(
                          targetOffset.clamp(0.0, maxScrollExtent),
                        );
                      }
                    });
                  }
                  return true; // 阻止继续滚动
                } else if (centerPosition >= maxPosition) {
                  // 滚动到底部（24:00）
                  final targetOffset =
                      maxPosition - componentHeight / 2 + paddingOffset;
                  if (targetOffset <= maxScrollExtent) {
                    WidgetsBinding.instance.addPostFrameCallback((_) {
                      if (_scrollController.hasClients) {
                        _scrollController.jumpTo(
                          targetOffset.clamp(0.0, maxScrollExtent),
                        );
                      }
                    });
                  }
                  return true; // 阻止继续滚动
                }
              }
              return false;
            },
            child: SingleChildScrollView(
              padding: EdgeInsets.symmetric(vertical: 380.w),
              controller: _scrollController,
              scrollDirection: Axis.vertical,
              physics: const ClampingScrollPhysics(),
              child: SizedBox(
                width: double.infinity,
                height: totalHeight,
                child: Row(
                  children: [
                    // 左侧间距 28px
                    SizedBox(width: 28.w),

                    // 时间轴绘制区域
                    ClipRRect(
                      borderRadius: BorderRadius.circular(8.r),
                      child: Container(
                        width: totalRulerWidth,
                        height: totalHeight,
                        child: CustomPaint(
                          painter: UnifiedTimeRulerPainter(
                            selectedTime: _currentScrollTime,
                            recordSegments: widget.recordSegments ?? [],
                            today: _today,
                            isCenterLineMode: true,
                          ),
                          size: Size(totalRulerWidth, totalHeight),
                        ),
                      ),
                    ),

                    // 右侧空白区域（可滑动）
                    const Expanded(child: SizedBox()),
                  ],
                ),
              ),
            ),
          ),

          // 固定的中心横线（不随滚动移动）
          Positioned.fill(
            child: IgnorePointer(
              child: Center(child: _buildCenterLineSimple()),
            ),
          ),

          // 中心线右侧的时间显示（不随滚动移动）
          Positioned(
            right: 10.w,
            top: 0,
            bottom: 0,
            child: IgnorePointer(
              child: Center(child: _buildCenterTimeSimple()),
            ),
          ),
        ],
      ),
    );
  }

  /// 构建简化的中心横线（用于居中显示）
  Widget _buildCenterLineSimple() {
    return Container(
      width: MediaQuery.of(context).size.width - 180.w,
      height: 4,
      child: Row(
        children: [
          // 左侧渐变淡出效果
          Container(
            width: 28.w,
            height: 4,
            decoration: BoxDecoration(
              gradient: LinearGradient(
                begin: Alignment.centerLeft,
                end: Alignment.centerRight,
                colors: [
                  const Color(0xFF047FF7).withValues(alpha: 0),
                  const Color(0xFF047FF7),
                ],
              ),
            ),
          ),
          // 主线条
          Expanded(
            child: Container(
              height: 4,
              decoration: BoxDecoration(
                color: const Color(0xFF047FF7),
                boxShadow: [
                  BoxShadow(
                    color: const Color(0xFF047FF7).withValues(alpha: 0.4),
                    blurRadius: 6,
                    spreadRadius: 2,
                  ),
                ],
              ),
            ),
          ),
          // 右侧渐变淡出效果
          Container(
            width: 20.w,
            height: 4,
            decoration: BoxDecoration(
              gradient: LinearGradient(
                begin: Alignment.centerLeft,
                end: Alignment.centerRight,
                colors: [
                  const Color(0xFF047FF7),
                  const Color(0xFF047FF7).withValues(alpha: 0),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  /// 构建简化的时间显示（用于居中显示）
  Widget _buildCenterTimeSimple() {
    if (_currentScrollTime == null) return const SizedBox.shrink();

    return Container(
      padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 10.h),
      decoration: BoxDecoration(
        color: const Color(0xFF047FF7),
        borderRadius: BorderRadius.circular(25),
        boxShadow: [
          BoxShadow(
            color: const Color(0xFF047FF7).withValues(alpha: 0.3),
            blurRadius: 8,
            spreadRadius: 2,
          ),
        ],
      ),
      child: Text(
        '${_currentScrollTime!.hour.toString().padLeft(2, '0')}:${_currentScrollTime!.minute.toString().padLeft(2, '0')}:${_currentScrollTime!.second.toString().padLeft(2, '0')}',
        style: const TextStyle(
          fontSize: 14,
          color: Colors.white,
          fontWeight: FontWeight.w600,
        ),
      ),
    );
  }

  /// 构建水平时间刻度尺（保留接口）
  Widget _buildHorizontalTimeRuler() {
    return Container(
      height: 120.h,
      color: const Color(0xFFEDF3FA),
      child: Center(
        child: Text(
          '水平模式暂未实现',
          style: TextStyle(fontSize: 16.sp, color: Colors.grey),
        ),
      ),
    );
  }
}

/// 统一的时间刻度尺绘制器
class UnifiedTimeRulerPainter extends CustomPainter {
  final DateTime? selectedTime;
  final List<Map<String, dynamic>> recordSegments;
  final DateTime today;
  final bool isCenterLineMode; // 是否为中心线模式

  // 使用与Widget相同的常量，确保一致性
  static const double hourHeight = 120.0;
  static const double timeWidth = 70.0; // 时间显示区域宽度
  static const double scaleWidth = 130.0; // 刻度尺区域宽度
  static const double verticalPadding = 20.0; // 上下内边距

  UnifiedTimeRulerPainter({
    required this.selectedTime,
    required this.recordSegments,
    required this.today,
    this.isCenterLineMode = false,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint();

    // 绘制背景
    _drawBackground(canvas, size, paint);

    // 绘制录像片段
    _drawRecordSegments(canvas, size, paint);

    // 绘制刻度线
    _drawScaleLines(canvas, size, paint);

    // 绘制时间标签
    _drawTimeLabels(canvas, size, paint);

    // 中心线模式不需要绘制选中线（由固定的中心线代替）
    if (!isCenterLineMode && selectedTime != null) {
      _drawSelectedLine(canvas, size, paint);
    }
  }

  /// 绘制背景
  void _drawBackground(Canvas canvas, Size size, Paint paint) {
    // 计算有效绘制区域（考虑内边距）
    final effectiveTop = verticalPadding;
    final effectiveHeight = size.height - 2 * verticalPadding;

    // 刻度尺区域背景（右侧130px区域）
    paint.color = const Color(0xFFC4DEFB).withValues(alpha: 0.3);
    canvas.drawRect(
      Rect.fromLTWH(timeWidth, effectiveTop, scaleWidth, effectiveHeight),
      paint,
    );

    // 刻度尺右边缘分界线
    paint.color = const Color(0xFFC4DEFB).withValues(alpha: 0.6);
    paint.strokeWidth = 1;
    canvas.drawLine(
      Offset(timeWidth + scaleWidth, effectiveTop),
      Offset(timeWidth + scaleWidth, effectiveTop + effectiveHeight),
      paint,
    );
  }

  /// 绘制录像片段
  void _drawRecordSegments(Canvas canvas, Size size, Paint paint) {
    paint.color = const Color(0xFFFF8A0A).withValues(alpha: 0.35);

    for (final segment in recordSegments) {
      final startTime = segment['startTime'] as DateTime?;
      final endTime = segment['endTime'] as DateTime?;

      if (startTime != null && endTime != null) {
        final startPos = _timeToPosition(startTime);
        final endPos = _timeToPosition(endTime);

        // 在刻度尺区域绘制录像片段
        canvas.drawRect(
          Rect.fromLTWH(timeWidth, startPos, scaleWidth, endPos - startPos),
          paint,
        );
      }
    }
  }

  /// 绘制刻度线
  void _drawScaleLines(Canvas canvas, Size size, Paint paint) {
    final scaleStartX = timeWidth;
    final scaleLineWidth = scaleWidth * 3 / 5; // 所有刻度线宽度为当前刻度尺宽度的5分之3

    // 主刻度线（每小时）- 使用5分3宽度
    paint.color = const Color(0xFF5880AD);
    paint.strokeWidth = 1;

    for (int hour = 0; hour <= 24; hour++) {
      final pos = verticalPadding + hour * hourHeight;
      canvas.drawLine(
        Offset(scaleStartX, pos),
        Offset(scaleStartX + scaleLineWidth, pos),
        paint,
      );
    }

    // 小刻度线（每10分钟）- 使用5分3宽度
    paint.color = const Color(0xFF5880AD);
    paint.strokeWidth = 0.5;

    for (int hour = 0; hour < 24; hour++) {
      for (int tenMin = 1; tenMin < 6; tenMin++) {
        // 1,2,3,4,5对应10,20,30,40,50分钟
        final minute = tenMin * 10;
        final pos =
            verticalPadding + hour * hourHeight + (minute / 60.0) * hourHeight;

        canvas.drawLine(
          Offset(scaleStartX, pos),
          Offset(scaleStartX + scaleLineWidth, pos),
          paint,
        );
      }
    }
  }

  /// 绘制时间标签
  void _drawTimeLabels(Canvas canvas, Size size, Paint paint) {
    final textPainter = TextPainter(textDirection: TextDirection.ltr);

    for (int hour = 0; hour < 24; hour++) {
      final pos = verticalPadding + hour * hourHeight;

      textPainter.text = TextSpan(
        text: '${hour.toString().padLeft(2, '0')}:00',
        style: const TextStyle(
          fontSize: 14,
          color: Color(0xFF555555),
          fontWeight: FontWeight.w500,
        ),
      );
      textPainter.layout();

      // 确保时间标签在时间区域内（左侧70px）
      final textX = (timeWidth - textPainter.width) / 2; // 居中显示
      textPainter.paint(canvas, Offset(textX, pos - textPainter.height / 2));
    }
  }

  /// 绘制选中线（只在刻度尺区域内）
  void _drawSelectedLine(Canvas canvas, Size size, Paint paint) {
    final selectedPos = _timeToPosition(selectedTime!);

    paint.color = const Color(0xFF5880AD);
    paint.strokeWidth = 3;

    // 只在刻度尺区域绘制选中线（从时间区域右边缘开始到刻度尺右边缘）
    canvas.drawLine(
      Offset(timeWidth, selectedPos),
      Offset(timeWidth + scaleWidth, selectedPos),
      paint,
    );
  }

  /// 时间转换为位置（包含内边距）
  /// ✅ 严格限制在 00:00 到 24:00 范围内
  double _timeToPosition(DateTime time) {
    // ✅ 严格限制时间范围：hour 必须在 0-23 之间
    final hour = time.hour.clamp(0, 23);
    final minute = time.minute.clamp(0, 59);
    final second = time.second.clamp(0, 59);

    // ✅ 计算位置，确保在有效范围内
    final position =
        verticalPadding + (hour + minute / 60.0 + second / 3600.0) * hourHeight;

    // ✅ 确保位置不超过最大有效位置（24:00 对应 verticalPadding + 24 * hourHeight）
    // totalHeight = 24 * hourHeight + 2 * verticalPadding
    // maxPosition = totalHeight - verticalPadding = verticalPadding + 24 * hourHeight
    final maxPosition = verticalPadding + 24 * hourHeight;

    return position.clamp(verticalPadding, maxPosition);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return oldDelegate is! UnifiedTimeRulerPainter ||
        oldDelegate.selectedTime != selectedTime ||
        oldDelegate.recordSegments != recordSegments ||
        oldDelegate.today != today ||
        oldDelegate.isCenterLineMode != isCenterLineMode;
  }
}
